package com.gzz.orchid.common.core.validation.validator;

import jakarta.validation.Constraint;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.Payload;
import lombok.extern.slf4j.Slf4j;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @EnumValidator(value = RoleEnum.class)
 */
@Target({ElementType.METHOD, ElementType.FIELD}) //在方法和属性上面起作用
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EnumValidator.Validator.class)
public @interface EnumValidator {
    Class<?> value();

    String message() default "The input parameter value is not in the correct enumeration";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    /**
     * 校验类逻辑定义
     */
    @Slf4j
    class Validator implements ConstraintValidator<EnumValidator, Object> {
        private final List<Object> values = new ArrayList<>();

        @Override
        public void initialize(EnumValidator enumValidator) {
            Class<?> clz = enumValidator.value();
            Object[] objects = clz.getEnumConstants();
            try {
                Method method = clz.getMethod("getCode");
                if (Objects.isNull(method)) {
                    throw new Exception(String.format("枚举对象{}缺少字段名为code的字段", clz.getName()));
                }
                Object value = null;
                for (Object obj : objects) {
                    value = method.invoke(obj);
                    values.add(value);
                }
            } catch (Exception e) {
                log.error("[处理枚举校验异常]", e);
            }
        }

        @Override
        public boolean isValid(Object value, ConstraintValidatorContext context) {
            return Objects.isNull(value) || values.contains(value);
        }
    }
}
